GLOBAL	_read_cr0, _write_cr0, _read_cr3, _write_cr3
GLOBAL  _read_msw,_lidt, _sgdt, _lgdt
GLOBAL  _int_08_hand, _int_09_hand, _int_74_hand, _int_80_hand, _excp_0_hand, _excp_04_hand, _excp_06_hand, _excp_11_hand
GLOBAL	outportb, inportb, EOI
GLOBAL  _mascaraPIC1, _mascaraPIC2, _Cli, _Sti
GLOBAL  _debug
GLOBAL	_Write, _Read
GLOBAL	_overflow, _invalid_opcode, _seg_not_present

EXTERN	GetTecladoKey
EXTERN	putVideoChar

EXTERN  int_08
EXTERN	int_09
EXTERN	int_74
EXTERN	int_80
EXTERN	excp_0
EXTERN	excp_04
EXTERN	excp_06
EXTERN	excp_11
EXTERN	mouse_handler




SECTION .text

; _read_cr0, _write_cr0: funciones para habilitar paginacion
_read_cr0:
	mov eax, cr0
	retn

_write_cr0:
	push ebp
	mov ebp, esp
	mov eax, [ebp+8]
	mov cr0,  eax
	pop ebp
	retn

; _read_cr3, _write_cr3: funciones para setear la direccion donde se encuentra
; 						 ubicado el directorio de tabla de paginas
_read_cr3:
	mov eax, cr3
	retn

_write_cr3:
	push ebp
	mov ebp, esp
	mov eax, [ebp+8]
	mov cr3, eax
	pop ebp
	retn	

_overflow:
		pusha
		mov		eax, 10000
		mov		ebx, 20000
		imul	eax,ebx
		into
		imul	eax,ebx
		into
		popa
		ret

_invalid_opcode:
		pusha
		jp		$ -1
		jp		$ -3
		jp		$ +1
		jp		$ +3
		popa
		ret

_seg_not_present:
		push ebp
		mov ebp,esp
		mov ax,[ebp-8]
		mov ds,ax
		mov bx,[ds:30]
		leave
		ret

_excp_0_hand:
        pusha
		call    excp_0
		popa
       iretd

_excp_04_hand:
        pusha
		call    excp_04
		popa
       iretd

_excp_06_hand:
        pusha
		call    excp_06
		popa
       iretd

_excp_11_hand:
        pusha
		call    excp_11
		popa
       iretd

_Cli:
	cli			; limpia flag de interrupciones
	ret

_Sti:

	sti			; habilita interrupciones por flag
	ret

_mascaraPIC1:			; Escribe mascara del PIC 1
	push    ebp
        mov     ebp, esp
        mov     ax, [ss:ebp+8]  ; ax = mascara de 16 bits
        out	21h,al
        pop     ebp
        retn

_mascaraPIC2:			; Escribe mascara del PIC 2
	push    ebp
        mov     ebp, esp
        mov     ax, [ss:ebp+8]  ; ax = mascara de 16 bits
        out	0A1h,al
        pop     ebp
        retn

_read_msw:
        smsw    ax		; Obtiene la Machine Status Word
        retn


_lidt:				; Carga el IDTR
        push    ebp
        mov     ebp, esp
        push    ebx
        ;mov     ebx, [ss: ebp + 6] ; ds:bx = puntero a IDTR
		;rol		ebx,16
	mov ebx, [ss: ebp + 8];
		lidt    [ds: ebx]          ; carga IDTR
        pop     ebx
        pop     ebp
        retn

_lgdt:
        push    ebp
        mov     ebp, esp
        push    ebx
        mov     ebx, [ss: ebp + 6] ; ds:bx = puntero a GDTR
		rol		ebx,16
		lgdt    [ds: ebx]          ; carga GDTR
        pop     ebx
        pop     ebp
        retn


_sgdt:				; Carga el GDTR
        push    ebp
        mov     ebp, esp
        push    ebx
        mov     ebx, [ss: ebp + 6] ; ds:bx = puntero a GDTR
		rol		ebx,16
		sgdt    [ds: ebx]          ; carga GDTR
        pop     ebx
        pop     ebp
        retn


_int_08_hand:				; Handler de INT 8 ( Timer tick)
        push    ds
        push    es                      ; Se salvan los registros
        pusha                           ; Carga de DS y ES con el valor del selector
        mov     ax, 10h			; a utilizar.
        mov     ds, ax
        mov     es, ax
        call    int_08
        mov	al,20h			; Envio de EOI generico al PIC
	out	20h,al
	popa
        pop     es
        pop     ds
        iret


_int_09_hand:				;manejador de teclado
	push	ds
	push	es
	pusha
	in	al,060h			;leo la entrada del teclado
	;mov	dx,[60h]
	;in	al, dx
	push	eax
	call	int_09			;llamo al driver de C para entender el teclado
	pop	eax
	mov	al,20h			; Envio de EOI generico al PIC
	out	20h,al
	popa
	pop	es
	pop	ds
	iret



_int_74_hand:
	call	mouse_handler
	iret

EOI:
	push	eax
	mov	al, 20h
	out	0A0h,al
	out	20h,al
	pop	eax
	ret

_int_80_hand:
	push	ds
	push	es
	pusha
;	cmp	eax,1		;para la shell
;	je	cshell
	cmp	eax,3		;para leer
	je	SysRead
	cmp	eax,4		;para escribir
	je	SysWrite
return:	popa
	pop	es
	pop	ds
	iret
SysRead:cmp 	bx,0
	jne	return
	popa
	pop	es
	pop	ds
	call	GetTecladoKey
	iret
	jmp 	return
SysWrite:cmp	bx,1
	jne	return
	push	ecx
	call	putVideoChar
	pop	ecx
	jmp	return
rot1:	push	ecx
	call	putVideoChar
	pop	ecx
	dec	edx
	jnz	rot1
	jmp 	return
;cshell:	call	shell
;	jmp 	return



_Write:
    push ebp
    mov ebp,esp
    push ebx
    push ecx
    push edx        ;backup registros

    mov eax, 4
    mov ebx, [ebp+8]    ; file descriptor
    mov ecx, [ebp+12]   ; buffer
   ; mov edx, [ebp+16]   ; size
;
    int 80h

    pop edx
    pop ecx
    pop ebx

    leave               ; stack original restaurado
    ret


_Read:
    push ebp
    mov ebp,esp
    push ebx
    push ecx
    push edx        ;backup registros

    mov eax, 3
    mov ebx, [ebp+8]    ; file descriptor
     ; mov edx, [ebp+16]   ; size
;
    int 80h

    pop edx
    pop ecx
    pop ebx

    leave               ; stack original restaurado
    ret

; Debug para el BOCHS, detiene la ejecució; Para continuar colocar en el BOCHSDBG: set $eax=0
;

outportb:
	push ebp
	mov ebp,esp

	push ecx
	push edx        ;backup registros

	mov edx, [DS:ebp+8]    ;
	mov al, [DS:ebp+12]   ;
	out dx,al

	pop edx
	pop ecx

	leave               ; stack original restaurado
	ret

inportb:
	push	ebp
	mov	ebp,esp

	push	edx

	mov	edx,[DS:ebp+8]
	in	al,dx

	pop	edx
	leave
	and	eax,0xFF
	ret


_debug:
        push    bp
        mov     bp, sp
        push	ax
vuelve:	mov     ax, 1
        cmp	ax, 0
	jne	vuelve
	pop	ax
	pop     bp
        retn
